package com.recharge.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.recharge.common.annotation.OperationLogDetail;
import com.recharge.common.domain.PageDO;
import com.recharge.common.enums.ErrorCode;
import com.recharge.common.enums.OperationLogType;
import com.recharge.common.result.ResultDO;
import com.recharge.common.result.ResultSupport;
import com.recharge.common.util.*;
import com.recharge.core.entity.DepositEntity;
import com.recharge.core.entity.TransactionEntity;
import com.recharge.core.mapper.DepositMapper;
import com.recharge.domain.query.DepositQueryDO;
import com.recharge.domain.vo.DepositDO;
import com.recharge.domain.vo.MerchantAccountDO;
import com.recharge.domain.vo.MerchantDO;
import com.recharge.domain.vo.TransactionDO;
import com.recharge.service.*;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 存款单表 服务实现类
 * </p>
 *
 * @author reagan
 * @since 2020-08-19
 */
@Service
public class DepositServiceImpl extends ServiceImpl<DepositMapper, DepositEntity> implements DepositService {

    @Autowired
    MerchantAccountService merchantAccountService;
    @Autowired
    MerchantService merchantService;
    @Autowired
    TransactionService transactionService;
    @Autowired
    DepositMapper depositMapper;
    @Autowired
    MerchantRepaymentService merchantRepaymentService;
    @Autowired
    RedisUtil redisUtil;
    @Autowired
    RedissonClient redissonClient;

    @Value("${node.name}")
    private Integer nodeName;

    private Logger logger = LoggerFactory.getLogger(this.getClass().getName());

    @Override
    public ResultDO add(DepositDO domain) {

        DepositEntity entity = new DepositEntity();

        ResultDO result = BeanUtilsExtends.copy(entity, domain);
        if (!result.isSuccess()) {
            logger.debug("error code：" + result.getErrorCode().getCode() + " msg" + result.getErrorCode().getMsg());
            return result;
        }

        boolean res = false;
        try {
            res = this.save(entity);
        } catch (Exception e) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
            logger.debug("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
            return result;
        }

        //判断r的值是否小于0.如果小于0 就代表添加失败
        if (!res) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.DEPOSIT_APPLY_FOR_ERROR);
            logger.debug("error code：" + ErrorCode.DEPOSIT_APPLY_FOR_ERROR.getCode() + " msg" + ErrorCode.DEPOSIT_APPLY_FOR_ERROR.getMsg());
            return result;
        }

        return result;
    }

    @Override
    public ResultDO edit(DepositDO domain) {

        DepositEntity entity = new DepositEntity();

        ResultDO result = BeanUtilsExtends.copy(entity, domain);
        if (!result.isSuccess()) {
            logger.debug("error code：" + result.getErrorCode().getCode() + " msg" + result.getErrorCode().getMsg());
            return result;
        }

        boolean res = false;
        try {
            res = this.updateById(entity);
        } catch (Exception e) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
            logger.debug("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
            return result;
        }

        //判断r的值是否小于0.如果小于0 就代表添加失败
        if (!res) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.USER_EDIT_ERROR);
            logger.debug("error code：" + ErrorCode.USER_EDIT_ERROR.getCode() + " msg" + ErrorCode.USER_EDIT_PASSWORD_ERROR.getMsg());
            return result;
        }

        return result;
    }

    @Override
    public ResultDO get(String id) {

        ResultDO result = new ResultSupport();
        DepositEntity entity = null;

        try {
            entity = this.getById(id);
        } catch (Exception e) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
            logger.debug("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
            return result;
        }

        DepositDO domain = getDomain(entity);

        result.setModel(ResultDO.FIRST_MODEL_KEY, domain);

        return result;
    }

    @Override
    public ResultDO remove(String id) {

        ResultDO result = new ResultSupport();

        boolean res = false;
        try {
            res = this.removeById(id);
        } catch (Exception e) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
            logger.debug("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
            return result;
        }

        //判断r的值是否小于0.如果小于0 就代表添加失败
        if (!res) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.USER_DELETE_ERROR);
            logger.debug("error code：" + ErrorCode.USER_DELETE_ERROR.getCode() + " msg" + ErrorCode.USER_DELETE_ERROR.getMsg());
            return result;
        }

        return result;
    }

    @Override
    public ResultDO removeByMerchantId(String merchantId) {
        ResultDO result = new ResultSupport();

        LambdaUpdateWrapper<DepositEntity> updateWrapper = Wrappers.<DepositEntity>lambdaUpdate()
                .eq(DepositEntity::getMerchantId, merchantId)
                .eq(DepositEntity::getStatus, Constant.DEPOSIT_VERIFICATION_UNKNOWN);
        try {
            baseMapper.delete(updateWrapper);
        } catch (Exception e) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.DEPOSIT_DELETE_ERROR);
            logger.debug("error code：" + ErrorCode.DEPOSIT_DELETE_ERROR.getCode() + " msg" + ErrorCode.DEPOSIT_DELETE_ERROR.getMsg());
            return result;
        }
        result.setSuccess(true);
        return result;
    }

    @Override
    public ResultDO find(DepositQueryDO query) {
        DepositEntity entity = new DepositEntity();
        ResultDO result = BeanUtilsExtends.copy(entity, query);
        if (!result.isSuccess()) {
            logger.debug("error code：" + result.getErrorCode().getCode() + " msg" + result.getErrorCode().getMsg());
            return result;
        }
        QueryWrapper<DepositEntity> wrapper = new QueryWrapper<>(entity);
        wrapper.lambda().eq(DepositEntity::getIsDelete, Constant.IS_DELETE_FALSE);

        Page<DepositEntity> page = new Page<>(query.getCurrentPage(), query.getPageSize());

        IPage<DepositEntity> iPage = null;

        try {
            iPage = baseMapper.selectPage(page, wrapper);
        } catch (Exception e) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.DEPOSIT_SELECT_ERROR);
            logger.debug("error code：" + ErrorCode.DEPOSIT_SELECT_ERROR.getCode() + " msg" + ErrorCode.DEPOSIT_SELECT_ERROR.getMsg());
            return result;
        }
        List<DepositDO> doList = getDomainList(iPage.getRecords());
        if (doList != null && doList.size() > 0) {
            for (DepositDO dep : doList) {
                Long amount = dep.getAmount();
                if (amount != null) {
                    dep.setAmount(amount / 1000);
                }
                Long confirmAmount = dep.getConfirmAmount();
                if (confirmAmount != null) {
                    dep.setConfirmAmount(confirmAmount / 1000);
                }
            }
        }

        PageDO<DepositDO> pageDO = new PageDO<>();
        pageDO.setCurrentPage(iPage.getCurrent());
        pageDO.setPageCount(iPage.getPages());
        pageDO.setPageSize(iPage.getSize());
        pageDO.setRowCount(iPage.getTotal());
        pageDO.setData(doList);

        result.setModel(ResultDO.FIRST_MODEL_KEY, pageDO);
        return result;
    }

    @Override
    public ResultDO findList(DepositQueryDO domain) {
        DepositEntity entity = new DepositEntity();
        ResultDO result = BeanUtilsExtends.copy(entity, domain);
        if (!result.isSuccess()) {
            logger.debug("error code：" + result.getErrorCode().getCode() + " msg" + result.getErrorCode().getMsg());
            return result;
        }
        QueryWrapper<DepositEntity> wrapper = new QueryWrapper<>(entity);

        //条件
        if(!TemplateUtils.isEmpty(domain.getId())){
            wrapper.lambda().eq(DepositEntity::getId,domain.getId());
        }
        if(!TemplateUtils.isEmpty(domain.getMerchantId())){
            wrapper.lambda().eq(DepositEntity::getMerchantId,domain.getMerchantId());
        }
        if(!TemplateUtils.isEmpty(domain.getType())){
            wrapper.lambda().eq(DepositEntity::getType,domain.getType());
        }
        if(!TemplateUtils.isEmpty(domain.getStatus())){
            wrapper.lambda().eq(DepositEntity::getStatus,domain.getStatus());
        }
        if(!TemplateUtils.isEmpty(domain.getStartTime())){
            wrapper.lambda().ge(DepositEntity::getApplicantDate,domain.getStartTime());
        }
        if(!TemplateUtils.isEmpty(domain.getEndTime())){
            wrapper.lambda().lt(DepositEntity::getApplicantDate,domain.getEndTime());
        }

        Page<DepositEntity> page = new Page<>(domain.getCurrentPage(),domain.getPageSize());
        IPage<DepositEntity> iPage = null;

        List<DepositEntity> list;
        try {
            iPage = baseMapper.selectInfoPage(page, wrapper);
        } catch(Exception e) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.DEPOSIT_SELECT_ERROR);
            logger.debug("error code：" + ErrorCode.DEPOSIT_SELECT_ERROR.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
            return result;
        }
        List<DepositDO> domainList = getDomainList(iPage.getRecords());

        PageDO<DepositDO> pageDO = new PageDO<>();
        pageDO.setCurrentPage(iPage.getCurrent());
        pageDO.setPageCount(iPage.getPages());
        pageDO.setPageSize(iPage.getSize());
        pageDO.setRowCount(iPage.getTotal());
        pageDO.setData(domainList);

        result.setModel(ResultDO.FIRST_MODEL_KEY, pageDO);

        return result;
//        ResultDO result = new ResultSupport();
//
//        Page<DepositEntity> page = new Page<>(domain.getCurrentPage(), domain.getPageSize());
//        IPage<DepositEntity> iPage = null;
//
//        try {
//            Map<String, Object> map = MapTool.bean2Map(domain);
//            iPage = baseMapper.selectListAndPage(page, map);
//        } catch (Exception e) {
//            result.setSuccess(false);
//            result.setErrorCode(ErrorCode.DEPOSIT_SELECT_ERROR);
//            logger.debug("error code：" + ErrorCode.DEPOSIT_SELECT_ERROR.getCode() + " msg" + ErrorCode.DEPOSIT_SELECT_ERROR.getMsg());
//            return result;
//        }
//        List<DepositDO> doList = getDomainList(iPage.getRecords());
//
//        PageDO<DepositDO> pageDO = new PageDO<>();
//        pageDO.setCurrentPage(iPage.getCurrent());
//        pageDO.setPageCount(iPage.getPages());
//        pageDO.setPageSize(iPage.getSize());
//        pageDO.setRowCount(iPage.getTotal());
//        pageDO.setData(doList);
//
//        result.setModel(ResultDO.FIRST_MODEL_KEY, pageDO);
//        return result;
    }



    @OperationLogDetail(detail = "加款申请", operationType = OperationLogType.ADD)
    @Override
    @Transactional(propagation= Propagation.REQUIRED, rollbackFor= Exception.class)
    public ResultDO applyDeposit(DepositDO domain, String userName) {

        DepositEntity depositEntity = new DepositEntity();
        ResultDO result = BeanUtilsExtends.copy(depositEntity, domain);
        if (!result.isSuccess()) {
            logger.debug("error code：" + result.getErrorCode().getCode() + " msg" + result.getErrorCode().getMsg());
            return result;
        }

        /*
            查询商户相关信息
         */
        MerchantDO merchantDO = null;
        MerchantAccountDO merchantAccountDO = null;
//        UserLoginDO userLoginDO = null;
        int CreditCount = 0;
        try {
            merchantDO = (MerchantDO) merchantService.get(domain.getMerchantId()).getModel(ResultDO.FIRST_MODEL_KEY);
            merchantAccountDO = (MerchantAccountDO) merchantAccountService.get(domain.getMerchantId()).getModel(ResultDO.FIRST_MODEL_KEY);
//            userLoginDO = (UserLoginDO) redisUtil.get(Constant.USER + userName);
            if (domain.getType() == Constant.DEPOSIT_TYPE_LONG_CREDIT){
                CreditCount = depositMapper.getCreditCount(domain.getMerchantId(), Constant.DEPOSIT_VERIFICATION_UNKNOWN);
            }
        } catch (Exception e) {
            logger.debug("查询存款所需参数失败: "+e.getMessage());
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
            return result;
        }
        if (CreditCount != 0 ){
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.APPLY_CREDIT_EXITS);
            logger.debug("已存在固定授信申请");
            return result;
        }
        if (merchantDO == null || merchantAccountDO == null) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.MERCHANT_INFO_ERROR);
            logger.debug("查询商户信息失败");
            return result;
        }
//        if (userLoginDO == null) {
//            result.setSuccess(false);
//            result.setErrorCode(ErrorCode.PARAM_LOGIN_USER_ERROR);
//            logger.debug("获取登录用户信息失败");
//            return result;
//        }

        // 真实姓名
//        String realName = "";
//        UserDetailDO userDetailDO = userLoginDO.getUserDetailDO();
//        if (userDetailDO != null && userDetailDO.getRealName() != null) {
//            realName = userDetailDO.getRealName();
//        }

        /*
            添加存款记录
         */
        // 存款单号
        depositEntity.setDepositNo(SnowflakeIdWorker.getNo());
        // 用户账号
        depositEntity.setAccountNo(merchantAccountDO.getAccountNo());
        // 申请人
        depositEntity.setApplicant(userName);
        // 存款状态: 0.待审核 1.审核通过 2.审核失败
        depositEntity.setStatus(Constant.DEPOSIT_VERIFICATION_UNKNOWN);
        // 交易号
        depositEntity.setTransactionNo(SnowflakeIdWorker.getNo());
        // 信用还款金额
        Long returnAmount = depositEntity.getReturnAmount();
        if (returnAmount == null) {
            // 确认余额加款金额
            depositEntity.setConfirmAmount(depositEntity.getAmount());
        } else {
            if (merchantAccountDO.getNoAmount() < returnAmount) {
                result.setSuccess(false);
                result.setErrorCode(ErrorCode.DEPOSIT_REPAYMENT_TOO_BIG);
                logger.debug("信用还款金额大于待还款金额");
                return result;
            }
            //确认余额加款金额
            depositEntity.setConfirmAmount(depositEntity.getAmount() - returnAmount);
            // 还款交易号
            depositEntity.setReTransactionNo(SnowflakeIdWorker.getNo());
        }
        int insert = 0;
        try {
            insert = baseMapper.insert(depositEntity);
        } catch (Exception e) {
            logger.debug(e.getMessage());
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }

        if (insert <= 0) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.DEPOSIT_APPLY_FOR_ERROR);
            logger.debug("添加存款记录失败");
            return result;
        }

        /*
            添加交易记录
         */
        TransactionDO transactionDO = new TransactionDO();
        // 商家账号名
        transactionDO.setAccountNo(merchantAccountDO.getAccountNo());
        // 节点名称
        transactionDO.setNodeName(nodeName);
        // 根据类型可以是订单号存款单号退款单号
        transactionDO.setIdentifierNo(depositEntity.getDepositNo());
        // 商户号
        transactionDO.setMerchantNo(merchantDO.getMerchantNo());
        // 设置状态 未处理
        transactionDO.setStatus(Constant.TRANSACTION_STATUS_2);
        //设置交易类型
        if (depositEntity.getType() == Constant.DEPOSIT_TYPE_LONG_CREDIT) {
            // 1.存款 2.提现 3.商品订单 4.退款 5.固定授信 6.临时还款
            transactionDO.setType(Constant.TRANSACTION_TYPE_5);
        } else {
            transactionDO.setType(Constant.TRANSACTION_TYPE_1);
        }

        // 交易号
        transactionDO.setTransactionNo(depositEntity.getTransactionNo());
        // 1.收入 2.支出
        transactionDO.setAmountType(Constant.INCOME);
        // 交易金额
        transactionDO.setAmount(depositEntity.getConfirmAmount());
        result = transactionService.add(transactionDO);
        if (!result.isSuccess()) {
            logger.debug("添加存款交易记录失败");
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return result;
        }

        if (returnAmount != null) {
            // 1.收入 2.支出
            transactionDO.setAmountType(Constant.EXPEND);
            transactionDO.setTransactionNo(depositEntity.getReTransactionNo());
            transactionDO.setAmount(depositEntity.getReturnAmount());
            transactionDO.setType(Constant.TRANSACTION_TYPE_6);
            result = transactionService.add(transactionDO);
            if (!result.isSuccess()) {
                logger.debug("添加存款交易记录失败");
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return result;
            }
        }

        result.setModel(ResultDO.FIRST_MODEL_KEY, getDomain(depositEntity));
        return result;
    }

    @OperationLogDetail(detail = "审核存款", operationType = OperationLogType.UPDATE)
    @Override
    @Transactional(propagation= Propagation.REQUIRED, rollbackFor= Exception.class)
    public ResultDO verifyDeposit(DepositDO domain, String userName) {
        ResultDO result = new ResultSupport();

//        UserLoginDO userLoginDO = null;
        DepositEntity depositEntity = null;
        MerchantAccountDO merchantAccountDO = null;
        TransactionEntity transactionEntity = new TransactionEntity();
        /*
            查询信息
         */
        try {
            // 查询登录用户信息
//            userLoginDO = (UserLoginDO) redisUtil.get(Constant.USER + userName);
            // 查询存款申请记录
            depositEntity = baseMapper.selectById(domain.getId());
            if (depositEntity == null) {
                result.setSuccess(false);
                result.setErrorCode(ErrorCode.DEPOSIT_INFO_GET_ERROR);
                logger.debug("获取存款信息失败");
                return result;
            }
            //查询商户账户信息
            merchantAccountDO = (MerchantAccountDO) merchantAccountService.get(depositEntity.getMerchantId()).getModel(ResultDO.FIRST_MODEL_KEY);
        } catch (Exception e) {
            logger.debug("获取存款信息失败: "+e.getMessage());
            result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
            result.setSuccess(false);
            return result;
        }
//        if (userLoginDO == null) {
//            result.setSuccess(false);
//            result.setErrorCode(ErrorCode.PARAM_LOGIN_USER_ERROR);
//            logger.debug("获取登录用户信息失败");
//            return result;
//        }
        if (merchantAccountDO == null){
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.MERCHANT_INFO_ERROR);
            logger.debug("获取商户信息失败");
            return result;
        }

        if (depositEntity.getStatus() != Constant.DEPOSIT_VERIFICATION_UNKNOWN){
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.VERIFICATION_STATUS_ERROR);
            logger.debug("存款状态异常,不可审核");
            return result;
        }

        // 真实姓名
//        String realName = "";
//        UserDetailDO userDetailDO = userLoginDO.getUserDetailDO();
//        if (userDetailDO != null) {
//            realName = userDetailDO.getRealName();
//        }

        depositEntity.setChecker(userName); // 审核人
        depositEntity.setCheckerDate(new Date()); // 审核时间

        //判断审核状态
        if (domain.getStatus() == Constant.DEPOSIT_VERIFICATION_SUCCESS) {
            /*
              设置余额、临时额度欠款、固定额度的逻辑
                预付款:
                    是否信用还款:
                        否: 1.添加余额 2.修改交易记录
                        是: 1.添加余额 2.减少临时额度欠款 3.修改交易记录(两条)
                信用款:
                    1.添加余额 2.增加临时额度欠款 3.修改交易记录
                固定授信:
                    1.修改固定授信 2.修改交易记录
             */
            // 信用还款金额
            Long returnAmount = depositEntity.getReturnAmount();
            // 确认添加余额
            Long confirmAmount = depositEntity.getConfirmAmount();

            switch (depositEntity.getType()) {
                case 1: // 预付款
                    logger.debug(String.format("depositId:%s => 为商户:%s 添加预付款 %s , 还款%s", depositEntity.getId(), depositEntity.getMerchantId(), confirmAmount, returnAmount));
                    // 判断是否信用还款
                    if (returnAmount != null && returnAmount >= 0) {

                        if (merchantAccountDO.getNoAmount() < returnAmount){
                            result.setSuccess(false);
                            result.setErrorCode(ErrorCode.DEPOSIT_REPAYMENT_TOO_BIG);
                            logger.debug("还款金额大于待还款金额");
                            return result;
                        }
                        // 减少临时额度欠款
                        result = merchantAccountService.addCredit(depositEntity.getMerchantId(), null, -returnAmount);
                        if (!result.isSuccess()) {
                            result.setSuccess(false);
                            result.setErrorCode(ErrorCode.MERCHANT_ACCOUNT_EDIT_NO_AMOUNT_ERROR);
                            logger.debug("修改临时信用款失败");
                            return result;
                        }

                        transactionEntity.setBeforeBalance((long) result.getModel(ResultDO.FIRST_MODEL_KEY));
                        transactionEntity.setBalance((long) result.getModel(ResultDO.SECOND_MODEL_KEY));
                        transactionEntity.setStatus(Constant.TRANSACTION_STATUS_1);
                        String reTransactionNo = depositEntity.getReTransactionNo();
                        // 判断交易号是否存在
                        if (TemplateUtils.isEmpty(reTransactionNo)){
                            result.setSuccess(false);
                            result.setErrorCode(ErrorCode.TRANSACTION_EDIT_NO_AMOUNT_ERROR);
                            logger.debug("修改临时信用款还款记录失败");
                            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                            return result;
                        }
                        // 修改临时款还款交易记录
                        boolean update = transactionService.update(transactionEntity
                                , new LambdaQueryWrapper<TransactionEntity>()
                                        .eq(TransactionEntity::getTransactionNo, reTransactionNo));
                        if (!update) {
                            result.setSuccess(false);
                            result.setErrorCode(ErrorCode.TRANSACTION_EDIT_NO_AMOUNT_ERROR);
                            logger.debug("修改临时信用款还款记录失败");
                            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                            return result;
                        }
                    }
                    if (confirmAmount == 0){
                        Long balance = merchantAccountDO.getBalance();
                        result.setModel(ResultDO.FIRST_MODEL_KEY, balance);
                        result.setModel(ResultDO.SECOND_MODEL_KEY, balance);
                    }else {
                        result = merchantAccountService.editBalance(depositEntity.getMerchantId(), confirmAmount);
                    }
                    break;
                case 2: // 信用款
                    // 增加临时额度欠款
                    if (!merchantAccountService.addCredit(depositEntity.getMerchantId(), null, confirmAmount).isSuccess()) {
                        result.setSuccess(false);
                        result.setErrorCode(ErrorCode.MERCHANT_ACCOUNT_EDIT_CREDIT_ERROR);
                        logger.debug("修改临时信用款失败");
                        return result;
                    }
                    logger.debug(String.format("depositId:%s => 为商户:%s 添加信用款 %s", depositEntity.getId(), depositEntity.getMerchantId(), confirmAmount));
                    // 添加余额
                    result = merchantAccountService.editBalance(depositEntity.getMerchantId(), confirmAmount);
                    break;
                case 4: // 固定授信
                    logger.debug(String.format("depositId:%s => 为商户:%s 添加长期信用款 %s", depositEntity.getId(), depositEntity.getMerchantId(), confirmAmount));
                    result = merchantAccountService.addCredit(depositEntity.getMerchantId(), depositEntity.getConfirmAmount(), null);
                    break;
                default: // 未找到
                    result.setSuccess(false);
                    break;
            }

            // 判断修改代理商资金是否成功
            if (!result.isSuccess()) {
                result.setSuccess(false);
                result.setErrorCode(ErrorCode.MERCHANT_EDIT_ACCOUNT_ERROR);
                logger.debug("添加余额失败");
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return result;
            }

            Long before = (Long) result.getModel(ResultDO.FIRST_MODEL_KEY);
            Long after = (Long) result.getModel(ResultDO.SECOND_MODEL_KEY);
            transactionEntity.setBeforeBalance(before);
            transactionEntity.setBalance(after);
            depositEntity.setBeforeBalance(before);
            depositEntity.setAfterBalance(after);
        }

        depositEntity.setStatus(domain.getStatus()); // 审核状态

        // 修改交易表信息状态
        if (domain.getStatus() == Constant.DEPOSIT_VERIFICATION_SUCCESS) {
            transactionEntity.setStatus(Constant.TRANSACTION_STATUS_1);
        } else if (domain.getStatus() == Constant.DEPOSIT_VERIFICATION_FAIL) {
            transactionEntity.setStatus(Constant.TRANSACTION_STATUS_0);
        } else {
            transactionEntity.setStatus(Constant.TRANSACTION_STATUS_2);
        }

        logger.debug(String.format("depositId:%s => 存款 修改交易记录 ", depositEntity.getId()));
        boolean update = transactionService.update(transactionEntity,
                new LambdaQueryWrapper<TransactionEntity>()
                        .eq(TransactionEntity::getTransactionNo, depositEntity.getTransactionNo())
                        .ne(TransactionEntity::getType, Constant.TRANSACTION_TYPE_6));
        if (!update) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.TRANSACTION_EDIT_DEPOSIT_ERROR);
            logger.debug("修改交易记录失败");
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return result;
        }

        logger.debug(String.format("id:%s => 存款 修改存款记录 ", depositEntity.getId()));
//        logger.debug("修改存款记录");
//        update = false;
//        try {
//            update = baseMapper.updateById(depositEntity) > 0;
//        } catch (Exception e) {
//            logger.debug(e.getMessage());
//            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
//        }

        RLock lock = redissonClient.getLock("LOCK_DEPOSIT" + domain.getId());
        try {
            if (lock.tryLock(30, TimeUnit.SECONDS)) {
                DepositEntity depo = baseMapper.selectById(domain.getId());
                if (depo == null || depo.getStatus() != Constant.DEPOSIT_VERIFICATION_UNKNOWN) {
                    logger.info("加款 > 申请已审核");
                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                    result.setSuccess(false);
                    result.setErrorCode(ErrorCode.VERIFICATION_STATUS_ERROR);
                    return result;
                }
                update = baseMapper.updateById(depositEntity) > 0;
            }
        } catch (Exception e) {
            logger.info(e.getMessage());
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            result.setErrorCode(ErrorCode.DEPOSIT_EDIT_ERROR);
            return result;
        } finally {
            lock.unlock();
        }

        if (!update) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.DEPOSIT_EDIT_ERROR);
//            logger.info("修改存款记录失败");
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return result;
        }
        result.setSuccess(true);
        result.setErrorCode(ErrorCode.SYSTEM_SUCCESS);
        return result;
    }

    /*@Deprecated
    @OperationLogDetail(detail = "关闭长期信用款", operationType = OperationLogType.UPDATE)
    @Override
    @Transactional
    public ResultDO closeCredit(DepositDO domain) {
        ResultDO result = new ResultSupport();

        UserLoginDO currentUser = null;
        List<DepositEntity> list = new ArrayList<>();
        MerchantAccountDO merchantAccountEntity = new MerchantAccountDO();
        try {
            currentUser = (UserLoginDO) SecurityUtils.getSubject().getPrincipal();
            // 查询存款单记录
            list = baseMapper.selectList(
                    new LambdaQueryWrapper<DepositEntity>()
                            .eq(DepositEntity::getMerchantId, domain.getMerchantId())
                            .eq(DepositEntity::getType, Constant.DEPOSIT_TYPE_LONG_CREDIT)
                            .eq(DepositEntity::getStatus, Constant.DEPOSIT_VERIFICATION_SUCCESS));

            merchantAccountEntity = (MerchantAccountDO) merchantAccountService.get(domain.getMerchantId()).getModel(ResultDO.FIRST_MODEL_KEY);
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (currentUser == null) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
            logger.debug("获取操作人信息失败");
            return result;
        }
        if (list.size() == 0) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.PARAM_GET_ERROR);
            logger.debug("关闭长期授信失败");
            return result;
        }
        // 判断是商户余额
        Long balance = merchantAccountEntity.getBalance();
        if (balance == null || balance < 0) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
            logger.debug("商户余额不足");
            return result;
        }

        // 判断存款单与信用款金额是否一致
        Long credit = merchantAccountEntity.getCredit();
        List<String> updateIds = new ArrayList<>();
        for (DepositEntity dep : list) {
            credit -= dep.getConfirmAmount();
            updateIds.add(dep.getId());
        }
        if (credit != 0L) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
            logger.debug("授信款金额校验异常");
            return result;
        }


        // 修改存款单状态
        DepositEntity entity = new DepositEntity();
        entity.setStatus(Constant.DEPOSIT_VERIFICATION_SUCCESS);
        int update = 0;
        try {
            update = baseMapper.update(entity, new LambdaQueryWrapper<DepositEntity>().in(DepositEntity::getId, updateIds));
        } catch (Exception e) {
            logger.warning(e.getMessage());
        }
        if (update <= 0) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
            logger.debug("修改存款单状态失败");
            return result;
        }

        // 清除信用款
        MerchantAccountEntity accountEntity = new MerchantAccountEntity();
        accountEntity.setId(merchantAccountEntity.getId());
        accountEntity.setCredit(0L);
        accountEntity.setModifiDate(new Date());
        accountEntity.setModifier(currentUser.getUsername());
        boolean updateAccount = false;
        try {
            updateAccount = merchantAccountService.updateById(accountEntity);
        } catch (Exception e) {
            logger.warning(e.getMessage());
        }
        if (!updateAccount) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
            logger.debug("修改授信款失败");
            return result;
        }

        // 添加日志记录
        logger.debug(String.format("系统操作 -> 关闭商户%s的授信款 %s 厘", domain.getMerchantId(), merchantAccountEntity.getCredit()));
        result.setSuccess(true);
        return result;
    }*/

//    @Override
////    public ResultDO getIds(String id) {
////
////        ResultDO result = new ResultSupport();
////        List<DepositEntity> entityList = null;
////        List<String> list = Arrays.asList(id.split(","));
////        try {
////            entityList = depositMapper.getByIds(list);
////        } catch (Exception e) {
////            result.setSuccess(false);
////            result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
////            logger.debug("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
////            return result;
////        }
////
//////        DepositDO domain = getDomain(entityList);
////
////        result.setModel(ResultDO.FIRST_MODEL_KEY, entityList);
////
////        return result;
////    }

    private DepositDO getDomain(DepositEntity entity) {

        //判断对象是否为空，为空就返回 空，不为空就进行下面的代码
        if (entity == null) {
            return null;
        }
        DepositDO domain = new DepositDO();

        domain = BeanUtilsExtends.copyProperties(domain, entity) ? domain : null;

        //判断拷贝数据到Dto对象是否成功，如果成功则返回domian，如果不成功就返回空
        return domain;
    }

    private List<DepositDO> getDomainList(List<DepositEntity> list) {
        //创建一个名为dolist的房源do类型的 list集合
        List<DepositDO> doList = new ArrayList<DepositDO>();

        //判断传入的list的集合的size是否大于0
        if (list.size() > 0) {
            //大于0是，遍历list，创建do类型的对象 调用getdomain方法
            for (DepositEntity entity : list) {

                DepositDO domain = this.getDomain(entity);

                //判断得到的domain 是否为空 不为空 就往dolist集合里面添加domian 为空就返回空
                if (domain == null) {
                    return null;
                }
                doList.add(domain);
            }
        } else {
            return null;
        }
        return doList;
    }

//    @Transactional
//    public ResultDO applyDeposityInfo(DepositEntity depositEntity, TransactionEntity transactionEntity) {
//        ResultSupport result = new ResultSupport();
//        /*
//            添加存款记录
//         */
//        if (baseMapper.insert(depositEntity) <= 0) {
//            throw new CustomException(500, "添加存款记录失败");
//        }
//
//        /*
//            添加交易记录
//         */
//        // 根据类型可以是 订单ID,提现单ID,存款单ID
//        transactionEntity.setMappingId(depositEntity.getId());
//        //transactionEntity = transactionService.insert(transactionEntity);
//
//        /*
//            返回
//         */
//        if (transactionEntity.getId() == null) {
//            throw new CustomException(500, "添加存款交易记录失败");
//        }
//
//        result.setSuccess(true);
//        return result;
//    }
//
//    @Transactional
//    public ResultDO exampleDeposityInfo(TransactionEntity transactionEntity, DepositEntity depositEntity) {
//        ResultSupport result = new ResultSupport();
//        boolean b1 =
//                transactionService.update(transactionEntity,
//                        new LambdaQueryWrapper<TransactionEntity>()
//                                .eq(TransactionEntity::getTransactionNo, depositEntity.getTransactionNo()));
//        if (!b1) {
//            throw new CustomException(500, "修改交易表失败");
//        }
//        boolean b2 = baseMapper.updateById(depositEntity) > 0;
//        if (!b2) {
//            throw new CustomException(500, "修改存款记录表失败");
//        }
//        result.setSuccess(true);
//        return result;
//    }

}
